﻿using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace VASJ.Common
{
    public class SerializationTool<T>
    {
        public static bool Save(string path, List<T> dataSource)
        {
            string fullPath = Path.Combine(path, FileNameAttribute.GetFileName<T>().Name);

            Logger.Log.InfoFormat("SerializationTool -> Save(list of object) -> fullPath: {0}", fullPath);

            FileStream fileStream = null;

            try
            {
                fileStream = new FileStream(fullPath, FileMode.CreateNew);

                XmlSerializer xmlSerializer = new XmlSerializer(typeof(List<T>));

                xmlSerializer.Serialize(fileStream, dataSource);

                fileStream.Close();

                //BinaryFormatter binaryFormatter = new BinaryFormatter();

                //binaryFormatter.Serialize(fileStream, dataSource);

                //fileStream.Close();

                SaveWithEndcoding(fullPath);

                return true;
            }
            catch (IOException ex)
            {
                Logger.Log.Error(ex.Message);
                throw ex;
            }
            finally
            {
                if (fileStream != null)
                {
                    fileStream.Close();
                }
            }
        }

        public static bool Save(string path, T obj)
        {
            string fullPath = Path.Combine(path, FileNameAttribute.GetFileName<T>().Name);

            Logger.Log.InfoFormat("SerializationTool -> Save(object) -> fullPath: {0}", fullPath);

            FileStream fileStream = null;

            try
            {
                fileStream = new FileStream(fullPath, FileMode.Create);

                XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));

                xmlSerializer.Serialize(fileStream, obj);

                fileStream.Close();

                //BinaryFormatter binaryFormatter = new BinaryFormatter();

                //binaryFormatter.Serialize(fileStream, obj);

                //fileStream.Close();

                SaveWithEndcoding(fullPath);

                return true;
            }
            catch (IOException ex)
            {
                Logger.Log.Error(ex.Message);
                throw ex;
            }
            finally
            {
                if (fileStream != null)
                {
                    fileStream.Close();
                }
            }
        }

        public static T Load(string path)
        {
            string fullPath = Path.Combine(path, FileNameAttribute.GetFileName<T>().Name);

            Logger.Log.InfoFormat("SerializationTool -> Load -> fullPath: {0}", fullPath);

            if (File.Exists(fullPath))
            {
                FileStream fileStream = null;

                try
                {
                    fileStream = new FileStream(fullPath, FileMode.Open);

                    XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));

                    T results = (T)xmlSerializer.Deserialize(fileStream);

                    fileStream.Close();

                    //BinaryFormatter binaryFormatter = new BinaryFormatter();

                    //T results = (T)binaryFormatter.Deserialize(fileStream);

                    //fileStream.Close();

                    return results;
                }
                catch (IOException ex)
                {
                    Logger.Log.Error(ex.Message);
                    return default(T);
                }
                finally
                {
                    if (fileStream != null)
                    {
                        fileStream.Close();
                    }
                }
            }
            else return default(T);
        }

        public static void SaveWithEndcoding(string fileName)
        {
            if (string.IsNullOrEmpty(fileName))
            {
                Logger.Log.ErrorFormat("Path file: {0} does not exist.", fileName);
                return;
            }

            if (!File.Exists(fileName))
            {
                Logger.Log.Error("File Configuration.xml does not exist.");
                return;
            }

            XmlDocument xmlDoc = new XmlDocument();

            xmlDoc.Load(fileName);

            XmlDeclaration xmlDecl = xmlDoc.CreateXmlDeclaration("1.0", "utf-8", null);

            if (xmlDoc.FirstChild.NodeType == XmlNodeType.XmlDeclaration)
            {
                xmlDoc.ReplaceChild(xmlDecl, xmlDoc.FirstChild);
            }
            else
            {
                xmlDoc.InsertBefore(xmlDecl, xmlDoc.DocumentElement);
            }

            xmlDoc.Save(fileName);
        }
    }
}